<!--
 * @Author: “ChengNan” 1429323234@qq.com
 * @Date: 2024-06-27 17:47:37
 * @LastEditors: 城南 1429323234@qq.com
 * @LastEditTime: 2024-06-28 09:47:32
 * @FilePath: /src/views/3.$set/setIndex.html
 * @Description: 
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
  <!-- and it's easy to individually load additional languages -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/go.min.js"></script>
  <script>
    window.hljs = hljs;
    window.hljs.highlightAll()
  </script>
</head>
<body>

  <div>
    <pre>
      <code class="language-javascript">
        /*
          在vue中，我们使用vue.$set(object, key, value)的原理
        */

        1. 使用Object.keys()获取 data 的所有 key ，然后遍历
        2. 使用Object.defineProperty() 为 Vue添加一个可枚举的 key 属性
        3. getter 获取 data 中的值，setter 设置 data中的值
        4. 属性描述符中需要设置 configurable 为 true ，否则无法修改属性
        7. 属性描述符中需要设置 value 为 getter 和 setter，否则无法获取和设置属性值

        Vue的实现，定义一个对象，此对象通过订阅发布模式结合 Object.defineProperty,
        遍历所有属性并为每个属性添加 getter 和 setter，实现响应式数据。
        

        function Vue(options = {}) {
          this.$data = options.data || {}
    
          proxy(this, this.$data)
    
          function proxy(targer, targerData) {
            Object.keys(targerData).forEach(key => {
              Object.defineProperty(targer, key, {
                configurable: true,
                enumerable: true,
                get() {
                  return targerData[key]
                },
                set(val) {
                  targerData[key] = val
                },
              })
            })
          }
        }
        var vm = new Vue({
          data: {
            name: '李华'
          }
        })
      </code>
    </pre>
  </div>

  
  <script>
    function Vue(options = {}) {
      this.$data = options.data || {}

      proxy(this, this.$data)

      function proxy(targer, targerData) {
        Object.keys(targerData).forEach(key => {
          Object.defineProperty(targer, key, {
            configurable: true,
            enumerable: true,
            get() {
              return targerData[key]
            },
            set(val) {
              targerData[key] = val
            },
          })
        })
      }
    }
    var vm = new Vue({
      data: {
        name: '李华'
      }
    })

    
    
  </script>
</body>
</html>